/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.weso.acota.dao;

import org.apache.tika.language.LanguageIdentifier;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.Iterator;
import java.util.Map;

import org.apache.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.TermAttribute;
import org.weso.acota.enhacer.LuceneEnhancer;
import org.weso.acota.to.ProviderTO;
import org.weso.acota.to.RequestSuggestionTO;
import org.weso.acota.to.SuggestionTO;
import org.weso.acota.to.TagTO;
import org.weso.acota.utils.EnglishStopAnalyzer;
import org.weso.acota.utils.SpanishStopAnalyzer;

import com.hp.hpl.jena.util.Tokenizer;

/**
 *
 * @author chema, weena
 */
@SuppressWarnings({ "deprecation", "unused" })
public class SuggestLuceneDAOImpl implements SuggestDAO {

	protected static Logger logger = Logger.getLogger(SuggestLuceneDAOImpl.class);
	private Analyzer analizaer = null;
	private static ProviderTO provider = new ProviderTO("Lucene Analizer");
	private RequestSuggestionTO request;
	private SuggestionTO suggest;
	
	
    public SuggestionTO suggest(RequestSuggestionTO doRequest) {
    	logger.debug("Initialize variables");
        request = doRequest;
        suggest = request.getSuggestions();
        suggest.setResource(request.getResource());
       
        //extracting terms of label
        try {
        	logger.debug("Extraction terms of label");
			extractingTerms("label", request.getResource().getLabel(), 10);
		} catch (IOException e) {
			logger.error("Don't have label to extract information", e);
			e.printStackTrace();
		}
		
		//extracting terms of descripcion
        try {
        	logger.debug("Extraction terms of description");
			extractingTerms("desciption", request.getResource().getDescription(), 5);
		} catch (IOException e) {
			logger.error("Don't have description to extract information", e);
			e.printStackTrace();
		}
        return suggest;
    }
    
    @SuppressWarnings({ "rawtypes", "unchecked" })
	private void extractingTerms(String tittle, String text, int relevance) throws IOException{
		//Language identification
    	LanguageIdentifier ld = new LanguageIdentifier(text);
    	if(ld.getLanguage().equals("es")){
    		logger.debug("switch to spanish analizer");
    		analizaer = new SpanishStopAnalyzer();
    	}else if(ld.getLanguage().equals("en")){
    		logger.debug("switch to english analizer");
    		analizaer = new EnglishStopAnalyzer();
    	}else{
    		logger.debug("language not supported");
    		analizaer = null;
    	}
    	
    	try{
    		logger.debug("Get tokens of texts");
        	TokenStream stream = analizaer .tokenStream(tittle, 
    				new StringReader(text));
    		TermAttribute termAttribute = stream.getAttribute(TermAttribute.class);
    		
    		while(true){
    			if(!stream .incrementToken())
    				break;
    			logger.debug("Add tag to suggestions");
    			TagTO tag = new TagTO();
    			tag.setLabel(termAttribute.term());
    			tag.setProvider(provider);
    			tag.setTagged(this.request.getResource());
    			this.suggest.getTags().add(tag);
    			
    			logger.debug("Add labels and weight to suggestions");
    			if(this.suggest .getLabels().containsKey(tag.getLabel())==true){
    				//Check if there is another tag with the same label
    				Iterator itr = this.suggest .getLabels().entrySet().iterator();
    				while (itr.hasNext()) {
    					Map.Entry e = (Map.Entry)itr.next();
    					if(e.getKey().equals(tag.getLabel())){
    						int valor = (Integer) e.getValue();
    						valor +=relevance;
    						e.setValue(valor);
    					}
    				}	
    			}else{
    				this.suggest .getLabels().put(tag.getLabel(), relevance);
    			}
    		}
    	}catch (Exception e) {
    		logger.error("\n\nLanguage not supported ("+ld.getLanguage()+")\n"+text);
		}
	}

	public ProviderTO getProvider() {
		logger.debug("Display provider name");
		return provider;
	}

}
